﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using BaseHelper;


namespace DeviceSDK.Radar.DaHua
{
    public class DaHua_ITC235
    {

        private static fDisConnectCallBack m_DisConnectCallBack;
        private static fHaveReConnectCallBack m_ReConnectCallBack;
        private static fAnalyzerDataCallBack m_AnalyzerDataCallBack;

        private static int iLastErr;



        //private static IntPtr[] UserHandlerList = new IntPtr[200];
        private static SortedList<int, string> slUserHandlerList = new SortedList<int, string>();

        private static bool IsInit = false;
        private static object locker = new object();

        public static bool IsConnected(string IP)
        {
            return slUserHandlerList.ContainsValue(IP);
        }

        //获取错误代码
        public static string Get_Error(int ret)
        {


            switch (ret)
            {
                case 0:
                    return "操作成功！";
                case 1:
                    return "操作失败！err" + iLastErr.ToString();
                case 2:
                    return "初始化接口失败！err" + iLastErr.ToString();
                case 3:
                    return "登录设备失败，请检测IP、用户名、密码和端口号！err" + iLastErr.ToString();
                case 4:
                    return "登录成功，但监听数据失败！err" + iLastErr.ToString();

                case 5:
                    return "初始化，设定回调接口出错！err" + iLastErr.ToString();

                case -1:
                    return "本设备不支持此命令！";
                default:
                    return "未知错误！";
            }
        }

        //设置初始化
        public static int Init()
        {
            try
            {
                lock (locker)
                {
                    if (!IsInit)
                    {
                        m_DisConnectCallBack = new fDisConnectCallBack(DisConnectCallBack);
                        m_ReConnectCallBack = new fHaveReConnectCallBack(ReConnectCallBack);
                        m_AnalyzerDataCallBack = new fAnalyzerDataCallBack(AnalyzerDataCallBack);



                        if(NETClient.Init(m_DisConnectCallBack, IntPtr.Zero, null))
                        {
                            NETClient.SetAutoReconnect(m_ReConnectCallBack, IntPtr.Zero);
                            IsInit=true;
                        }
                    }
                }
                return IsInit?0:2;
            }
            catch (Exception ex)
            {
                LogHelper.Err("DeviceSDK.Radar.DaHua.DaHua_ITC235.cs", "Init()", ex);
            }
            return 2;
        }

        //设置关闭监听
        public static int Set_Close()
        {
            try
            {

                foreach (IntPtr UserID in slUserHandlerList.Keys)
                {
                    try
                    {
                        bool result = NETClient.Logout(UserID);
                      
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Err("DeviceSDK.Radar.DaHua.DaHua_ITC235.cs", "Set_Close()->UserHandlerList", ex);
                    }
                }

                NETClient.Cleanup();

                IsInit = false;
            }
            catch (Exception ex)
            {
                LogHelper.Err("DeviceSDK.Radar.DaHua.DaHua_ITC235.cs", "Set_Close()", ex);
            }
            GC.Collect();
            return 0;
        }


        public static int Set_Connect(string IP, string Port, string UserName, string Password)
        {
            try
            {
                lock (locker)
                {
                    if (IsInit == false)
                    {
                        int ret = Init();
                        if (ret != 0)
                            return ret;
                    }
                }

                if (slUserHandlerList.ContainsValue(IP))
                    return 0;

                ushort DVRPortNumber = Port.Length == 0 ? (ushort)37777 : (ushort)Convert.ToInt32(Port);

                NET_DEVICEINFO_Ex m_DeviceInfo = new NET_DEVICEINFO_Ex();
                IntPtr UserID = NETClient.Login(IP, DVRPortNumber, UserName, Password, EM_LOGIN_SPAC_CAP_TYPE.TCP, IntPtr.Zero, ref m_DeviceInfo);

                if (UserID == IntPtr.Zero)
                {
                    return 3;// (int)iLastErr;  登录设备失败，请检测IP、用户名、密码和端口号！
                }
                else
                {
                    slUserHandlerList[UserID.ToInt32()] = IP;
                    return Set_Listen(UserID);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Err("DeviceSDK.Radar.DaHua.DaHua_ITC235.cs", "Set_Listen(IP...)", ex);
                return 3;
            }
        }


        private static int Set_Listen(IntPtr UserID)
        {
            try
            {
                IntPtr EventID = NETClient.RealLoadPicture(UserID, 0, (uint)EM_EVENT_IVS_TYPE.TRAFFIC_FLOWSTATE, false, m_AnalyzerDataCallBack, UserID, IntPtr.Zero);
                if (EventID == IntPtr.Zero)
                {
                    return 4;// (int)iLastErr; 登录成功，但监听数据失败！
                }
                else
                {
                    return 0;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Err("DeviceSDK.Radar.DaHua.DaHua_ITC235.cs", "Set_Listen(UserID)", ex);
                return 4;
            }
        }

        private static void DisConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser)
        {
            string IP = Marshal.PtrToStringAnsi(pchDVRIP);

            if (slUserHandlerList.ContainsKey(lLoginID.ToInt32()))
                slUserHandlerList.Remove(lLoginID.ToInt32());

        }

        private static void ReConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser)
        {
            string IP = Marshal.PtrToStringAnsi(pchDVRIP);
            slUserHandlerList[lLoginID.ToInt32()]=IP;
        }

        private static int AnalyzerDataCallBack(IntPtr lAnalyzerHandle, uint dwEventType, IntPtr pEventInfo, IntPtr pBuffer, uint dwBufSize, IntPtr dwUser, int nSequence, IntPtr reserved)
        {
            EM_EVENT_IVS_TYPE type = (EM_EVENT_IVS_TYPE)dwEventType;
            string IP = "";

            if (!slUserHandlerList.ContainsKey(dwUser.ToInt32()))
            {
                return 0;
            }


            IP = slUserHandlerList[dwUser.ToInt32()];
 
            switch (type)
            {
                case EM_EVENT_IVS_TYPE.TRAFFIC_FLOWSTATE:
                    {
                        NET_DEV_EVENT_TRAFFIC_FLOW_STATE info = (NET_DEV_EVENT_TRAFFIC_FLOW_STATE)Marshal.PtrToStructure(pEventInfo, typeof(NET_DEV_EVENT_TRAFFIC_FLOW_STATE));

                        //如果通道数量是0
                        if(info.nStateNum==0)
                            break;

                        int AvgJam = 0;
                        int AvgSpeed = 0;
                        int AvgSpaceOccupy = 0;
                        int CarCount = 0;
                        int BigCarCount = 0, MidCarCount = 0, SmallCarCount = 0;


                        for (int i = 0; i < info.nStateNum; i++)
                        {
                            //Console.WriteLine(info.stuStates[i].emJamState.ToString());


                            NET_TRAFFIC_FLOW_STATE state = info.stuStates[i];

                            AvgSpeed += Convert.ToInt32( state.fAverageSpeed);
                            AvgSpaceOccupy += Convert.ToInt32(state.fTimeOccupyRatio);
                            CarCount += (int)state.dwFlow;
                            BigCarCount += state.nLargeTruckVehicles;
                            MidCarCount += state.nMidTruckVehicles;
                            SmallCarCount += state.nSaloonCarVehicles;

                            //string line = string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8}\r\n", DateTime.Now.ToString(), state.nState, state.dwFlow, state.dwState, state.fTimeOccupyRatio,state.fDensity, state.fTimeHeadway, state.fSpaceOccupyRatio, state.fSpaceHeadway, state.fAverageSpeed, state.fAverageLength);
                            //System.IO.File.AppendAllText("d:\\log.csv", line,Encoding.Default);

                            AvgJam += (int)state.dwState;

                            
                            //Console.Write(state.nVolume); Console.Write("\t");
                            //Console.Write(state.nUnderSpeedVehicles); Console.Write("\t");
                            //Console.Write(state.nFlowRate); Console.Write("\t");
                            //Console.Write(state.dBackOfQueue); Console.Write("\t");
                            //Console.Write(state.fSpaceHeadway); Console.Write("\t");
                            //Console.Write(state.emJamState.ToString()); Console.Write("\t");
                            //Console.Write(state.dwState); Console.Write("\r\n");

                        }

                        AvgJam = 4 - AvgJam / info.nStateNum;
                        if (AvgJam < 0) AvgJam = 0;

                        AvgSpeed /= info.nStateNum;
                        AvgSpaceOccupy /= info.nStateNum;


                        //Console.WriteLine("IP:{7}   车辆数量：{0}，大车数量：{1}，中车数量：{2}，小车数量：{3}，平均速度：{4}，空间占有率：{5}，拥堵状态：{6}", CarCount, BigCarCount, MidCarCount, SmallCarCount, AvgSpeed, AvgSpaceOccupy, AvgJam, IP);

                   
                        RadarHandler.TrafficeDataArrive(RadarDataType.DaHua, IP, AvgJam, CarCount, BigCarCount, MidCarCount, SmallCarCount, AvgSpaceOccupy, AvgSpeed);

                    }
                    break;
            }


            //Console.WriteLine(type.ToString());
            return 0;
            //if (TrafficeDataArriveRealTimeEvent != null)
            //    TrafficeDataArriveRealTimeEvent(DeviceID, State, Speed, QueLen);


            //if (TrafficeDataArriveEvent != null)
            //    TrafficeDataArriveEvent(DeviceID, AvgSpeed.ToString(), AvgSpaceOccupy.ToString(), CarCount.ToString());
        }
    }
}
